package net.aiion.weave.impl.ui.xhtml;

import net.aiion.weave.spi.xml.XmlContext;
import net.aiion.weave.spi.xml.XmlEventFactory;
import net.aiion.weave.spi.xml.XmlSink;
import net.aiion.weave.spi.xml.events.CharactersXmlEvent;
import net.aiion.weave.spi.xml.events.ElementEndXmlEvent;
import net.aiion.weave.spi.xml.events.ElementStartXmlEvent;
import net.aiion.weave.spi.xml.events.XmlEvent;

public class XhtmlTransformer implements XmlSink
{
    private static final String LOCAL_NAME_TEXTAREA = "textarea";

    private boolean textAreaVisited;
    private boolean textAreaEmpty;

    public XhtmlTransformer() {
    }

    @Override
    public void handleXmlEvent(final XmlContext aXmlContext) {
        final XmlEvent xmlEvent = aXmlContext.getXmlEvent();
        switch (xmlEvent.getType()) {
        case XmlEvent.START_ELEMENT:
            transformStartElement(aXmlContext, (ElementStartXmlEvent) xmlEvent);
            break;
        case XmlEvent.CHARACTERS:
            transformCharacters(aXmlContext, (CharactersXmlEvent) xmlEvent);
            break;
        case XmlEvent.END_ELEMENT:
            transformEndElement(aXmlContext, (ElementEndXmlEvent) xmlEvent);
            break;
        default:
            break;
        }
    }

    private void transformStartElement(final XmlContext aXmlContext, final ElementStartXmlEvent aXmlStartElement) {
        if (LOCAL_NAME_TEXTAREA.equals(aXmlStartElement.getName().getLocalName())) {
            textAreaVisited = true;
            textAreaEmpty = true;
        }

        aXmlContext.forwardEvent();
    }

    private void transformCharacters(final XmlContext aXmlContext, final CharactersXmlEvent aXmlCharacters) {
        if (textAreaVisited) {
            textAreaEmpty = false;
        }

        aXmlContext.forwardEvent();
    }

    private void transformEndElement(final XmlContext aXmlContext, final ElementEndXmlEvent aXmlEndElement) {
        if (!LOCAL_NAME_TEXTAREA.equals(aXmlEndElement.getName().getLocalName())) {
            aXmlContext.forwardEvent();
            return;
        }

        textAreaVisited = false;
        if (textAreaEmpty) {
            aXmlContext.forwardXmlEvent(XmlEventFactory.getInstance().createCharacters(""));
            aXmlContext.forwardXmlEvent(aXmlEndElement);
        } else {
            aXmlContext.forwardEvent();
        }
    }
}
